<!--
 * @Description:
 * @Author: dh
 * @Date: 2022-01-21 13:41:19
 * @LastEditors: dh
 * @LastEditTime: 2022-12-28 11:41:15
-->
<template>
	<div v-for="item of num" :key="item" ref="setItemRef">
		{{ item }}
	</div>
	<div ref="point" class="point point-flicker">123</div>
</template>

<script lang="ts">
import { ref, Ref, onUpdated, computed, defineComponent, nextTick, onMounted, isRef, unref, shallowRef, shallowReactive, triggerRef } from 'vue';

export default defineComponent({
	setup() {
		const point = ref(null);
		onMounted(() => {
			console.log('refs', point);
		});

		const itemRefs = ref<Array<HTMLDivElement>>([]);
		const setItemRef = (el: HTMLDivElement) => {
			itemRefs.value.push(el);
		};

		onUpdated(() => {
			console.log(itemRefs);
		});

		const num = ref(4);
		nextTick(() => {
			setTimeout(() => {
				num.value = 5;
			}, 2000);
		});

		const a = ref(1); // 自动推断
		const b = ref<number>(2); // 泛型推断
		const c: Ref<number> = ref(2); // 手动赋值Ref类型
		console.log(c);

		const add = function (a: Ref<number>, b: Ref<number>) {
			return computed<number>(() => a.value + b.value);
		};
		add(a, b);

		const val = unref(a); // 如果参数是 ref，则返回.value，否则返回参数本身
		console.log(val);
		const flag = isRef(a); // 检查某个值是否为 ref
		console.log(flag);

		// TODO shallowRef 是 只会响应第一层，也就是通过.value 直接赋值，但是 ref 改变会调用 triggerRef ，会更新所有的 ref、shallowRef，此时 shallowRef 会响应
		// TODO shallowReactive 同理
		const shallowRefData = shallowRef([1]);

		shallowRefData.value.push(2); // 只有这样是不能响应
		triggerRef(shallowRefData); // 这样上面就能响应

		shallowRefData.value = [2]; // 能响应

		return {
			itemRefs,
			setItemRef,
			num,
			point,
		};
	},
});
</script>
